package com.creatingrevolutions.vbukit.lib;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import android.util.Base64;
import android.util.Log;

public class InternetUtils
{
	/**
	 * Execute a POST to our Vbukit server and return byte[].
	 * 
	 * @param url
	 * @param params
	 * @return
	 */
	public static synchronized InternetResponseModel executePost(String url,
			List<NameValuePair> params)
	{
		String TAG = "VbukitLib - executePost";
		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost request = new HttpPost(url);
		
		try
		{
			request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
			HttpResponse response = client.execute(request);
			// String fileName = response.getHeaders("name");
			
			Header header = response.getFirstHeader("Content-Disposition");
			Log.e(TAG, "Headers: " + header);
			
			Log.d(TAG, "Response: " + response);
			InputStream in = response.getEntity().getContent();
			
			byte[] content = readBytes(in);
			in.close();
			
			InternetResponseModel model = new InternetResponseModel();
			model.headers = header;
			model.response = content;
			
			return model;
			
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * Execute a POST to our Vbukit server and return String.
	 * 
	 * @param url
	 * @param params
	 * @return
	 */
	public static synchronized String executeJsonPost(String url,
			List<NameValuePair> params)
	{
		String TAG = "VbukitLib - executeJsonPost";
		String retValue = null;
		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost request = new HttpPost(url);
		
		try
		{
			request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
			HttpResponse response = client.execute(request);
			// String fileName = response.getHeaders("name");
			
			Header header = response.getFirstHeader("Content-Disposition");
			Log.e(TAG, "Headers: " + header);
			
			Log.d(TAG, "Response: " + response);
			InputStream in = response.getEntity().getContent();
			
			byte[] content = readBytes(in);
			in.close();
			
			retValue = new String(content, HTTP.UTF_8);
			
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return retValue;
	}
	
	/**
	 * Internal and auxiliar method.
	 * 
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	private static byte[] readBytes(InputStream inputStream) throws IOException
	{
		// this dynamically extends to take the bytes you read
		ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
		
		// this is storage overwritten on each iteration with bytes
		int bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];
		
		// we need to know how may bytes were read to write them to the
		// byteBuffer
		int len = 0;
		while ((len = inputStream.read(buffer)) != -1)
		{
			byteBuffer.write(buffer, 0, len);
		}
		
		// and then we can return your byte array.
		return byteBuffer.toByteArray();
	}
	
	public Hashtable<String, String> htHeaders = null;
	
	public InternetResponseModel executeGET(final String url)
	{
		if (url == null || url.trim().length() == 0) return null;
		
		if (url.trim().toLowerCase().startsWith("https"))
		{
			try
			{
				InputStream content = getInputStream(url, "", "");
				
				if (content != null)
				{
					byte[] bytes = readBytes(content);
					content.close();
					
					InternetResponseModel model = new InternetResponseModel();
					model.headers = null;
					model.response = bytes;
					
					return model;
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		
		StringBuilder builder = new StringBuilder();
		HttpClient client = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		if ( htHeaders != null ) {
			Enumeration<String> en = htHeaders.keys();
			while ( en.hasMoreElements() ) {
				String key = en.nextElement();
				String value = htHeaders.get(key);
				System.out.println("Header Key: " + key + " Header value: " + value);
				httpGet.setHeader(key, value);
			}
			htHeaders = null;
		}
		try
		{
			byte[] bytes = null;
			
			HttpResponse response = client.execute(httpGet);
			StatusLine statusLine = response.getStatusLine();
			int statusCode = statusLine.getStatusCode();
			Log.e("executeGET", "statusCode: " + statusCode);
			
			HttpEntity entity = response.getEntity();
			InputStream content = entity.getContent();
			/*
			 * BufferedReader reader = new BufferedReader( new
			 * InputStreamReader(content)); String line; while ((line =
			 * reader.readLine()) != null) { builder.append(line); }
			 */
			
			Header header = response.getFirstHeader("Content-Disposition");
			Log.e("executeGET", "Headers: " + header);
			
			bytes = readBytes(content);
			content.close();
			
			InternetResponseModel model = new InternetResponseModel();
			model.headers = header;
			model.response = bytes;
			
			return model;
		}
		catch (ClientProtocolException e)
		{
			e.printStackTrace();
			return null;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return null;
		}
		
	}
	
	private InputStream getInputStream(String urlStr, String user,
			String password)
	{
		try
		{
			URL url = new URL(urlStr);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			
			// Create the SSL connection
			SSLContext sc;
			sc = SSLContext.getInstance("TLS");
			sc.init(null, null, new java.security.SecureRandom());
			conn.setSSLSocketFactory(sc.getSocketFactory());
			
			// Use this if you need SSL authentication
			String userpass = user + ":" + password;
			String basicAuth = "Basic "
					+ Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT);
			conn.setRequestProperty("Authorization", basicAuth);
			
			// set Timeout and method
			conn.setReadTimeout(7000);
			conn.setConnectTimeout(7000);
			conn.setRequestMethod("POST");
			conn.setDoInput(true);
			
			// Add any data you wish to post here
			
			conn.connect();
			return conn.getInputStream();
		}
		catch (Exception e)
		{
			return null;
		}
	}
	
	
	
	public InternetResponseModel downloadDropboxFile(String url)
	{
		try
		{
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			InternetResponseModel model = 
					InternetUtils.executePost(url, params);
			return model;
		}
		catch (Exception e)
		{
			// An error occurred.
			e.printStackTrace();
			return null;
		}
	}
}
